package com.ygqh.baby.controller.admin;

import com.foxinmy.weixin4j.exception.WeixinException;
import com.foxinmy.weixin4j.mp.api.NotifyApi;
import com.foxinmy.weixin4j.mp.message.NotifyMessage;
import com.foxinmy.weixin4j.mp.message.TemplateMessage;
import com.foxinmy.weixin4j.mp.model.User;
import com.foxinmy.weixin4j.token.TokenHolder;
import com.foxinmy.weixin4j.tuple.Text;
import com.foxinmy.weixin4j.util.StringUtil;
import com.ygqh.baby.ao.*;
import com.ygqh.baby.constant.Constant;
import com.ygqh.baby.po.*;
import com.ygqh.baby.redis.RedisDao;
import com.ygqh.baby.service.*;
import com.ygqh.baby.service.wechat.message.YgTemplateMessage;
import com.ygqh.baby.utils.DateConvertUtils;
import com.ygqh.baby.utils.JsonUtils;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.stream.Collectors;

@Controller
@RequestMapping("/admin/weixin")
public class WeixinMessageController extends BaseController<Object, java.lang.Long> {

    @Autowired
    private YgWeixinMessageService ygWeixinMessageService;
    @Autowired
    private YgUserService ygUserService;

    @Autowired
    private WxMpMessageService wxMpMessageService;
    @Autowired
    private WxMpAuthorityService wxMpAuthorityService;
    @Autowired
    private YgWeixinMenuDayService ygWeixinMenuDayService;
    @Autowired
    private WxAttentionService wxAttentionService;
    @Autowired
    private WxSmallAuthorityService wxSmallAuthorityService;
    @Autowired
    private YgAgentService ygAgentService;
    @Autowired
    private SmsService smsService;
    @Value("${promotion.link}")
    protected String promotionLink;
    @Value("${micro.msg.appId}")
    protected String appId;
    @Autowired
    private RedisDao redisDao;
    @Value("${image.upload.temp.url}")
    private String tempFilePath;

    @RequestMapping("searchWeixinMessage")
    @ResponseBody
    public Map<String, Object> searchWeixinMessage(String title, QueryInfo queryInfo) {
        ResultSet<YgWeixinMessage> resultSet = ygWeixinMessageService.search(queryInfo, title);

        return resultSet.toDatatables(null);
    }

    @RequestMapping("sendWeixinMessage")
    @ResponseBody
    public Message saveWeixinMessage(String weixinMessage, HttpServletRequest request, HttpServletResponse response) throws WeixinException {
        YgWeixinMessage p = JsonUtils.toObject(weixinMessage, YgWeixinMessage.class);
        // List<User> wxUsers = this.getAllWxUser(p.getUserName());
        List<String> allOpenIds = this.getAllOpenIds(p.getUserName());
        ExecutorService fixedThreadPool = Executors.newFixedThreadPool(10);
        p.setFirstData(p.getFirstData().replace("\\", "\n"));

        for (int i = 0; i < allOpenIds.size(); i++) {
            final int index = i;
            System.err.println("===============" + allOpenIds.get(index) + "==========");
            fixedThreadPool.execute(new Runnable() {
                @Override
                public void run() {
                    switch (p.getWxMessageType()) {
                        case BindIngMsg:
                            wxMpMessageService.sendBindMsg(p.getFirstData(), p.getLinkUrl(), "微信商城账号", allOpenIds.get(index), p.getKeyword2Data(),
                                    p.getRemarkData());
                            break;
                        case ProductService:
                            wxMpMessageService.sendServiceExpressMsg(p.getFirstData(), p.getLinkUrl(), p.getKeyword1Data(), p.getKeyword2Data(),
                                    allOpenIds.get(index), p.getKeyword3Data(), p.getRemarkData());
                            break;
                        case NewAction:
                            wxMpMessageService.sendActionMsg(p.getFirstData(), p.getLinkUrl(), "微信商城账号", allOpenIds.get(index), p.getKeyword2Data(),
                                    p.getKeyword3Data(), p.getKeyword4Data(), p.getRemarkData());
                            break;
                        default:
                            break;
                    }

                }
            });

        }
        fixedThreadPool.shutdown();
        return SUCCESS_MESSAGE;
    }

    @RequestMapping("sendUserByPre48Hour")
    @ResponseBody
    public Message sendUserByPre48Hour(String userName, String content, String callback) {

        GregorianCalendar gc = new GregorianCalendar();
        gc.add(5, -2);
        System.err.println(gc.getTime());
        List<String> list = new ArrayList<String>();
        if (!userName.equals("")) {
            YgUser yguser = ygUserService.findByUserName(userName);
            list.add(yguser.getOpenId());
        } else {
            list = ygWeixinMenuDayService.getOpenId(gc.getTime());
        }
        List<String> openlist = list;

        ExecutorService fixedThreadPool = Executors.newFixedThreadPool(10);
        for (int i = 0; i < list.size(); i++) {

            final int index = i;
            fixedThreadPool.execute(new Runnable() {

                @Override
                public void run() {
                    String msg = content;
                    Text text = new Text(msg);
                    NotifyMessage notifyMessage = new NotifyMessage(openlist.get(index), text);
                    NotifyApi notifyAPI = new NotifyApi(wxMpAuthorityService.findTokenHolder());
                    try {
                        notifyAPI.sendNotify(notifyMessage);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            });
        }
        fixedThreadPool.shutdown();
        return SUCCESS_MESSAGE;

    }

    /*
     * @RequestMapping("sendUserByPre48HourAuto")
     *
     * @ResponseBody public Message sendUserByPre48HourAuto(String
     * userName,String content,String callback) { SimpleDateFormat format=new
     * SimpleDateFormat("yyy-MM-dd"); String date=format.format(new Date());
     * date=date.replaceAll("-",""); String co =
     * "亲爱的宝妈们，yiigoo壹果天猫旗舰店直播秒杀马上开始，全场19元起！多款春夏单品29元，39元秒杀，49元封顶！抢到就是赚的！复制这条信息￥tP8N0stx5sU￥后打开手机淘宝   马上关注直播！"
     * ;
     *
     * GregorianCalendar gc=new GregorianCalendar(); gc.add(5, -2);
     *
     * List<String> list=new ArrayList<String>(); YgUser
     * yguser=ygUserService.findByUserName(userName);
     * list.add(yguser.getOpenId()); list =
     * ygWeixinMenuDayService.getOpenId(gc.getTime()); List<String>
     * openlist=list;
     *
     * ExecutorService fixedThreadPool = Executors.newFixedThreadPool(10); for
     * (int i = 0; i < list.size(); i++) {
     *
     * final int index = i; fixedThreadPool.execute(new Runnable() {
     *
     * @Override public void run() { String msg =co; Text text = new Text(msg);
     * NotifyMessage notifyMessage = new NotifyMessage(openlist.get(index),
     * text); NotifyApi notifyAPI = new
     * NotifyApi(wxMpAuthorityService.findTokenHolder()); try {
     * notifyAPI.sendNotify(notifyMessage); } catch (Exception e) {
     * e.printStackTrace(); } } }); } fixedThreadPool.shutdown(); return
     * SUCCESS_MESSAGE;
     *
     * }
     */

    /*
     * @RequestMapping("sendUserByPre48HourTest")
     *
     * @ResponseBody public Message sendUserByPre48HourTest(String
     * userName,String content,String callback) { SimpleDateFormat format=new
     * SimpleDateFormat("yyy-MM-dd"); String date=format.format(new Date());
     * date=date.replaceAll("-",""); String co =
     * "夏天，防晒、防蚊、防空调啦，新款防晒衣、防蚊裤、空调衫已备好，海边必备泳衣和ins风水杯团购中，想要的麻麻抓紧下手！新客专享，夏季T恤，还有麻麻的条纹帆布包，低至49元！每日秒杀，款式超多，价格美丽，69元起！还有300-50优惠券别忘了领，任意订单满100加9元换购质量超好的有机棉袜一双哦~ "
     * +"<a href='http://m.yiigoo.com/mall/index.html?sourceCode="+date+
     * "'> 点击详情</a>";
     *
     * GregorianCalendar gc=new GregorianCalendar(); gc.add(5, -2); String
     * s=date; List<String> list=new ArrayList<String>(); YgUser
     * yguser=ygUserService.findByUserName(userName);
     * list.add(yguser.getOpenId()); list =
     * ygWeixinMenuDayService.getOpenId(gc.getTime()); List<String>
     * openlist=list;
     *
     * ExecutorService fixedThreadPool = Executors.newFixedThreadPool(10); for
     * (int i = 0; i < list.size(); i++) {
     *
     * final int index = i; fixedThreadPool.execute(new Runnable() {
     *
     * @Override public void run() {
     *
     * News news=new News(); news.addArticle("每日秒杀,已经开始",null,
     * "http://m.yiigoo.com/images/second/"+s+".png",
     * "http://m.yiigoo.com/product/seconds.html?sourceCode="+s);
     * news.addArticle("比凉鞋更更更舒服的鞋子，这个夏天尽情撒野去！", null,
     * "http://img.yiigoo.com/product/2018/04/10/1523363632456423338-800*800.jpg",
     * "http://m.yiigoo.com/product/list.html?key=一体织轻盈帆布鞋&cname=一体织轻盈帆布鞋&sourceCode="
     * +s); news.addArticle("百搭好穿的男童T恤，一件怎么能够~",null,
     * "http://img.yiigoo.com/product/2018/04/10/1523362425354104204-800*800.jpg",
     * "http://m.yiigoo.com/product/product.html?productId=912&sourceCode="+s);
     * news.addArticle("日本进口抗UV50+与ins风加持，告别丑丑的防晒服！", null,
     * "http://img.yiigoo.com/product/2018/04/03/1522729112668742518-800*800.jpg",
     * "http://m.yiigoo.com/product/product.html?productId=885&sourceCode="+s);
     * news.addArticle("火爆全球的网红游泳圈，阳光沙滩好夏日~", null,
     * "http://img.yiigoo.com/product/2018/04/10/1523351575175756475-800*800.jpg",
     * "http://m.yiigoo.com/product/list.html?key=泳圈&cname=泳圈&sourceCode="+s);
     *
     * NotifyMessage notifyMessage = new NotifyMessage(openlist.get(index),
     * news); NotifyApi notifyAPI = new
     * NotifyApi(wxMpAuthorityService.findTokenHolder()); try {
     * notifyAPI.sendNotify(notifyMessage); } catch (Exception e) {
     * e.printStackTrace(); } } }); } fixedThreadPool.shutdown(); return
     * SUCCESS_MESSAGE;
     *
     * }
     */

    @RequestMapping("getPre48HourCount")
    @ResponseBody
    public Integer getPre48HourCount() {
        GregorianCalendar gc = new GregorianCalendar();
        gc.add(5, -2);
        System.err.println(gc.getTime());
        List<String> list = ygWeixinMenuDayService.getOpenId(gc.getTime());
        return list.size();

    }

    private List<YgUser> getUserList(String userName) {
        List<YgUser> userList = null;
        if (userName.equals("")) {
            QueryInfo queryInfo = new QueryInfo(0, 100);// 此参数无效
            userList = ygUserService.selectUserByPage(queryInfo);
        } else {
            userList = new ArrayList<YgUser>();
            userList.add(ygUserService.findByUserName(userName));
        }

        return userList;
    }

    private List<User> getAllWxUser(String userName) throws WeixinException {

        List<User> list = null;
        if (StringUtil.isNotBlank(userName)) {
            YgUser user = ygUserService.findByUserName(userName);
            list = new ArrayList<User>();
            User wxuser = new User();
            wxuser.setOpenId(user.getOpenId());
            wxuser.setNickName(user.getNickName());
            list.add(wxuser);
        } else {

            list = wxMpAuthorityService.findAllFollowing();
        }
        return list;
    }

    private List<String> getAllOpenIds(String userName) throws WeixinException {

        List<String> list = null;
        if (StringUtil.isNotBlank(userName)) {
            YgUser user = ygUserService.findByUserName(userName);
            list = new ArrayList<String>();
            list.add(user.getOpenId());
        } else {
            list = wxMpAuthorityService.findAllOpenIds();
        }
        return list;
    }

    @RequestMapping("searchWeixinMenu")
    @ResponseBody
    public Map<String, Object> searchWeixinMenu(QueryInfo queryInfo, String q) {
        ResultSet<YgWeixinMenuDay> resultSet = ygWeixinMenuDayService.search(queryInfo, q);
        return resultSet.toDatatables(null);

    }

    @RequestMapping("sendSmall")
    @ResponseBody
    public Message sendSmall(Date startDate, String sourceCode, String userName, @RequestParam(defaultValue = "140") Integer ygSeoId) {
        if (StringUtils.isNotBlank(userName) && userName.equals("15911009019")) {
            YgTemplateMessage tplMessage = new YgTemplateMessage("o26750AF4s2RJvy2lrEJv64oC8vM", "UVBbpsNAJQcMnnYqTQh5KXuwGKoqobgAw4tBMqEeuGQ", "卡券领取成功通知",
                    null, "f99c389bce97b75717faaf8466930793");
            tplMessage.pushHead("#323232", "卡券领取成功通知");
            tplMessage.pushItem("keyword1", "#c32234", "100元券已到账");
            tplMessage.pushItem("keyword2", "#c32234", "61特惠进行中");
            tplMessage.pushItem("keyword3", "#c32234", "有机棉T恤3件189，新款裙子3件298");
            tplMessage.setEmphasisKeyword("keyword1.DATA");
            tplMessage.setPage("pages/index/index?sourceCode=" + sourceCode);
            wxMpMessageService.sendTmplMsg$Small(tplMessage);
        } else {
            List<WxAttention> list = wxAttentionService.selectAllAttention(startDate, ygSeoId, Constant.YIIGOO_PLATFORM_NO);

            ExecutorService fixedThreadPool = Executors.newFixedThreadPool(10);
            for (int i = 0; i < list.size(); i++) {
                System.err.println(list.get(i).getOpenId());
                final int index = i;
                fixedThreadPool.execute(new Runnable() {

                    @Override
                    public void run() {
                        YgTemplateMessage tplMessage = new YgTemplateMessage(list.get(index).getOpenId(), "UVBbpsNAJQcMnnYqTQh5KXuwGKoqobgAw4tBMqEeuGQ",
                                "卡券领取成功通知", null, list.get(index).getEvent());
                        tplMessage.pushHead("#323232", "卡券领取成功通知");
                        tplMessage.pushItem("keyword1", "#c32234", "100元券已到账");
                        tplMessage.pushItem("keyword2", "#c32234", "61特惠进行中");
                        tplMessage.pushItem("keyword3", "#c32234", "有机棉T恤3件189，新款裙子3件298");
                        tplMessage.setEmphasisKeyword("keyword1.DATA");
                        tplMessage.setPage("pages/index/index?sourceCode=" + sourceCode);
                        wxMpMessageService.sendTmplMsg$Small(tplMessage);
                        wxAttentionService.updateUpdateTime(list.get(index).getId());

                    }
                });
            }
            fixedThreadPool.shutdown();
        }
        return SUCCESS_MESSAGE;
    }

    @RequestMapping("sendSmallNewCustomer")
    @ResponseBody
    public Message sendSmallNewCustomer(Date startDate, String sourceCode, @RequestParam(defaultValue = "140") Integer ygSeoId) {

        List<WxAttention> list = wxAttentionService.selectAttentionList(startDate, ygSeoId, Constant.YIIGOO_PLATFORM_NO);

        ExecutorService fixedThreadPool = Executors.newFixedThreadPool(10);
        for (int i = 0; i < list.size(); i++) {
            System.err.println(list.get(i).getOpenId());
            final int index = i;
            fixedThreadPool.execute(() -> {
                YgTemplateMessage tplMessage = new YgTemplateMessage(list.get(index).getOpenId(), "F4ICNNAXOaehS2MLzilYjUzYx9W9V8rhoN5dVPVlEGA", "活动参与成功通知",
                        null, list.get(index).getEvent());
                tplMessage.pushHead("#323232", "活动参与成功通知");
                tplMessage.pushItem("keyword1", "#c32234", "特价且免邮");
                tplMessage.pushItem("keyword2", "#c32234", "首页搜索框输入特价");
                tplMessage.setEmphasisKeyword("keyword1.DATA");
                tplMessage.setPage("pages/index/index?sourceCode=" + sourceCode);
                wxMpMessageService.sendTmplMsg$Small(tplMessage);
                WxAttention wxAttention = list.get(index);
                // 更新关注信息的时间
                wxAttention.setId(list.get(index).getId());
                wxAttention.setUpdateTime(new Date());
                wxAttentionService.update(wxAttention);

            });
        }
        fixedThreadPool.shutdown();
        return SUCCESS_MESSAGE;
    }

    @RequestMapping("refreshSmallToken")
    @ResponseBody
    public Message refreshSmallToken() throws WeixinException {
        TokenHolder tokenHolder = wxSmallAuthorityService.findTokenHolder();
        tokenHolder.refreshToken();
        return Message.success(1);
    }

    @RequestMapping("refreshWxToken")
    @ResponseBody
    public Message refreshWxToken() throws WeixinException {
        TokenHolder tokenHolder = wxMpAuthorityService.findTokenHolder();
        tokenHolder.refreshToken();
        return Message.success(1);
    }

    /**
     * 女王-会员升级通知
     * <p>
     * 注：调用前需要把userType=UserAgent修改为Ordinary
     *
     * @return
     */
    @RequestMapping("sendMemberUpGradeToOldVip")
    @ResponseBody
    public Message sendMemberUpGradeToOldVip() {
        List<YgUser> userList = ygUserService.findByLevel(10);
        if (CollectionUtils.isEmpty(userList)) {
            return SUCCESS_MESSAGE;
        }
        System.out.println("女王总数：" + userList.size());
        String title = "会员升级通知";
        String memberLevel = "您的女王权益已升级";
        String checkStatus = "升级成功";
        String remark = "女王陛下，您的女王权益已全面升级，在全场打折的同时还可以邀请闺蜜们一起享优惠哦，快去看看吧";
        String link = "/channel/queenChange.html";
        ExecutorService fixedThreadPool = Executors.newFixedThreadPool(10);
        int count = 0;
        for (YgUser ygUser : userList) {
            if (ygUser.isUserAgent()) { // 过滤已成为代理的用户
                continue;
            }
            count++;
            fixedThreadPool.execute(() -> wxMpMessageService.sendMemberUpgrade(ygUser, title, memberLevel, checkStatus, remark, link));
        }
        System.out.println("共发送通知女王数：" + count);
        fixedThreadPool.shutdown();
        return SUCCESS_MESSAGE;
    }

    /**
     * 现代理-会员升级通知
     * <p>
     * 注：调用前需要把userType=UserAgent修改为Ordinary
     *
     * @return
     */
    @RequestMapping("sendMemberUpGradeToUserAgentByPass")
    @ResponseBody
    public Message sendMemberUpGradeToUserAgentByPass() {
        List<YgAgent> agentList = ygAgentService.findByCheckStatus(Arrays.asList(CheckStatus.Pass.name(), CheckStatus.WaitingCancel.name()));
        String title = "会员升级通知";
        String memberLevel = "您已升级为女王";
        String checkStatus = "升级成功";
        String remark = "您好，代理制和女王卡整合升级为壹+计划，可同时享受女王和代理双重权益，拼团的商品也可享受返利哦，快去看看吧";
        String link = "/channel/agentChange.html";
        System.out.println("现代理总数：" + agentList.size());
        return sendMemberUpGradeToUserAgent(agentList, title, memberLevel, checkStatus, remark, link);
    }

    /**
     * 取消的代理-会员升级通知
     * <p>
     * 注：调用前在yg_agent表中把需要的用户数据（添加或者修改）审核状态为Waiting
     *
     * @return
     */
    @RequestMapping("sendMemberUpGradeToUserAgentByWaiting")
    @ResponseBody
    public Message sendMemberUpGradeToUserAgentByWaiting() {
        List<YgAgent> agentList = ygAgentService.findByCheckStatus(Arrays.asList(CheckStatus.Waiting.name()));
        String title = "会员升级通知";
        String memberLevel = "您已升级为女王";
        String checkStatus = "升级成功";
        String remark = "您好，代理制和女王卡整合升级为壹+计划，可同时享受女王和代理双重权益，现诚邀您加入壹+计划，体验壹+计划的福利权益，快去看看吧";
        String link = "/channel/agentChange.html";
        System.out.println("取消的代理总数：" + agentList.size());
        return sendMemberUpGradeToUserAgent(agentList, title, memberLevel, checkStatus, remark, link);
    }

    public Message sendMemberUpGradeToUserAgent(List<YgAgent> agentList, String title, String memberLevel, String checkStatus, String remark, String link) {
        if (CollectionUtils.isEmpty(agentList)) {
            return SUCCESS_MESSAGE;
        }
        Map<Long, List<YgAgent>> map = agentList.stream().collect(Collectors.groupingBy(YgAgent::getUserId));
        ExecutorService fixedThreadPool = Executors.newFixedThreadPool(10);
        int count = 0;
        for (Map.Entry<Long, List<YgAgent>> entry : map.entrySet()) {
            List<YgAgent> list = entry.getValue();
            if (CollectionUtils.isEmpty(list)) {
                continue;
            }
            Long userId = entry.getKey();
            YgUser ygUser = ygUserService.findById(userId);
            if (ygUser.isUserAgent()) { // 过滤掉已成为代理用户
                continue;
            }
            if (ygUser.getLevel().compareTo(10) == 0) { // 女王用户优先调用：女王-会员升级通知
                continue;
            }
            count++;
            fixedThreadPool.execute(() -> wxMpMessageService.sendMemberUpgrade(ygUser, title, memberLevel, checkStatus, remark, link));
        }
        System.out.println("发送总数：" + count);
        fixedThreadPool.shutdown();
        return SUCCESS_MESSAGE;
    }

    @RequestMapping("sendMemberUpGradeByUserId")
    @ResponseBody
    public Message sendMemberUpGradeByUserId(Long userId, Integer level) {
        YgUser ygUser = ygUserService.findById(userId);
        String title = "会员升级通知";
        String memberLevel = null;
        String checkStatus = "升级成功";
        String remark = null;
        String link = null;
        if (level.compareTo(10) == 0) {
            memberLevel = "您的女王权益已升级";
            remark = "女王陛下，您的女王权益已全面升级，在全场打折的同时还可以邀请闺蜜们一起享优惠哦，快去看看吧";
            link = "/channel/queenChange.html";
        } else {
            memberLevel = "您已升级为女王";
            remark = "您好，代理制和女王卡整合升级为壹+计划，可同时享受女王和代理双重权益，拼团的商品也可享受返利哦，快去看看吧";
            link = "/channel/agentChange.html";
        }
        return wxMpMessageService.sendMemberUpgrade(ygUser, title, memberLevel, checkStatus, remark, link);
    }

    /**
     * 发送给女王待办事项
     *
     * @param userName
     * @return
     */
    @RequestMapping("sendTodoTasksByUserAgent")
    @ResponseBody
    public Message sendTodoTasksByUserAgent(String userName, @RequestParam(required = false, defaultValue = "1") Integer level) {
        if (StringUtils.isNotBlank(userName)) {
            YgUser ygUser = ygUserService.findByUserName(userName);
            return sendTodoTasks(ygUser);
        }
        List<YgUser> userList = ygUserService.findByUserType(UserType.UserAgent);
        userList = userList.stream().filter(o -> o.getLevel().compareTo(level) == 0).collect(Collectors.toList());
        if (CollectionUtils.isEmpty(userList)) {
            return Message.success(null);
        }
        ExecutorService fixedThreadPool = Executors.newFixedThreadPool(10);
        for (YgUser ygUser : userList) {
            fixedThreadPool.execute(() -> sendTodoTasks(ygUser));
        }
        fixedThreadPool.shutdown();
        return Message.success("女王用户总数", userList.size());
    }

    private Message sendTodoTasks(YgUser ygUser) {
        String title = "女王大人，61礼券请笑纳";
        String content = "儿童节专属女王券及新旧权益对比。";
        Date dateTime = new Date();
        String remark = "点击了解详情";
        String link = "/static/1527850428.html?source=Wechat";
        if (StringUtils.isNotBlank(ygUser.getOpenId())) {
            wxMpMessageService.sendTodoTasks(ygUser, title, content, dateTime, remark, link);
        }
        if (StringUtils.isNotBlank(ygUser.getTelPhone())) {
            smsService.sendSms(ygUser.getTelPhone(), "女王大人儿童节快乐！为您奉上61专属女王券！女王权益已升级，请点击链接查看详情http://t.cn/R1NRQ9w");
        }
        return Message.success(null);
    }

    @RequestMapping("sendNewUserList")
    @ResponseBody
    public Message sendNewUserList(String userName, Date startDate, HttpServletRequest request, HttpServletResponse response) throws WeixinException {
        YgWeixinMessage p = new YgWeixinMessage();
        p.setFirstData("【专享】60减20优惠券已到账");
        p.setLinkUrl("http://m.yiigoo.com/mall/index.html?sourceCode=newcustomer0605");
        p.setKeyword2Data("有机棉T恤3件189元；超美连衣裙3件298元；满299赠包；");
        p.setRemarkData("全场低至29元；还可叠加用券。");
        List<String> allOpenIds = new ArrayList<String>();
        if (userName.equals("15911009019")) {
            allOpenIds.add(ygUserService.findByUserName("15911009019").getOpenId());
        } else {
            List<YgUser> list = ygUserService.selectNewUserList(startDate);
            for (YgUser uu : list) {
                allOpenIds.add(uu.getOpenId());
            }
        }

        ExecutorService fixedThreadPool = Executors.newFixedThreadPool(10);
        p.setFirstData(p.getFirstData().replace("\\", "\n"));

        for (int i = 0; i < allOpenIds.size(); i++) {
            final int index = i;
            System.err.println("===============" + allOpenIds.get(index) + "==========");
            fixedThreadPool.execute(() -> wxMpMessageService.sendBindMsg(p.getFirstData(), p.getLinkUrl(), "微信商城账号", allOpenIds.get(index), p.getKeyword2Data(), p.getRemarkData()));

        }
        fixedThreadPool.shutdown();
        return SUCCESS_MESSAGE;
    }

    /**
     * 发送优惠券过期提醒
     * <p>
     * sourceCode 格式：优惠券id_quan_优惠券面值_时间格式
     *
     * @param userName
     * @return
     */
    @RequestMapping("sendCouponOverdueReminder")
    @ResponseBody
    public Message sendCouponOverdueReminder(String userName) {
        List<YgUser> userList = getSendUserListWithTest(userName, "All", "294");
        ExecutorService fixedThreadPool = Executors.newFixedThreadPool(10);
        for (YgUser user : userList) {
            fixedThreadPool.execute(() -> wxMpMessageService.sendOverdueReminder(user, "150元优惠券今日过期。\n夏季商品清仓最后倒计时，错过等一年。",
                    "/mall/index.html?sourceCode=quan_150_20180731", "", "壹果商城", DateConvertUtils.formatDateTime(new Date())));
        }
        fixedThreadPool.shutdown();
        return Message.success(userList.size());
    }

    /**
     * 发送 活动参与成功通知 model = 1 ：指定时间以前下过单，指定时间以后没有下过单的用户; model = 2
     * ：指定时间到现在注册并且没下过单的用户;
     *
     * @param userName
     * @return
     */
    @RequestMapping("sendActionSuccess")
    @ResponseBody
    public Message sendActionSuccess(String userName, @RequestParam String userType) {
        List<YgUser> userList = getSendUserListWithTest(userName, userType, "2018-01-01");
        String sourceCode = DateConvertUtils.format(new Date());
        ExecutorService fixedThreadPool = Executors.newFixedThreadPool(10);
        for (YgUser user : userList) {
            fixedThreadPool.execute(() -> {
                if (userType.equals("UnOrder")) {
                    sendActionSuccess("季末大减价，全场29元起。爆款T恤短裤199元任选4件。满399元再送原价299元儿童专业太阳镜，还有超高颜值亲子装安利，出街晒娃秀恩爱必备。",
                            "/mall/index.html?sourceCode=" + sourceCode, "", user, "季末大减价", "立即开始");
                } else if (userType.equals("UnOrderWithRegister")) {
                    sendActionSuccess("您账户有20元优惠券未使用。季末大减价，全场29元起。爆款T恤短裤199元任选4件。满399元再送原价299元儿童专业太阳镜，还有超高颜值亲子装安利，出街晒娃秀恩爱必备。",
                            "/mall/index.html?sourceCode=" + sourceCode, "", user, "季末大减价", "立即开始");
                }
            });
        }
        fixedThreadPool.shutdown();
        return Message.success(userList.size());
    }

    private Message sendActionSuccess(String first, String link, String remark, YgUser user, String keyword1, String keyword2) {
        link = promotionLink + link;
        String tempId = wxMpMessageService.getWxMsgTempId(WxMessageType.ActionSuccess);
        TemplateMessage tplMessage = new TemplateMessage(user.getOpenId(), tempId, first, link);
        tplMessage.pushHead("#323232", first);
        tplMessage.pushItem("keyword1", "#323232", keyword1);
        tplMessage.pushItem("keyword2", "#323232", keyword2);
        tplMessage.pushItem("remark", "#323232", remark);
        Message message = wxMpMessageService.sendTemplateMessage(tplMessage);
        return message;
    }

    /**
     * model = 1 ：指定时间以前下过单，指定时间以后没有下过单的用户; model = 2 ：指定时间到现在注册并且没下过单的用户;mode =
     * 3:所有女王
     *
     * @param userName
     * @return
     */
    private List<YgUser> getSendUserListWithTest(String userName, String userType, String... param) {
        List<YgUser> userList = new ArrayList<>();
        if (StringUtils.isNotBlank(userName)) {
            userList.add(ygUserService.findByUserName(userName));
        } else {
            userList.addAll(getSendUserList(userType, param));
        }
        return userList;
    }

    private List<YgUser> getSendUserList(String userType, String... param) {
        List<YgUser> list = null;
        switch (userType) {
            case "UnOrder": // 指定时间以前下过单，指定时间以后没有下过单的用户
                list = ygUserService.findOpenIdByNotOrderWithOrderTime(StringUtils.isNotBlank(param[0]) ? DateConvertUtils.parse(param[0], "yyyy-MM-dd") : null);
                break;
            case "UnOrderWithRegister": // 指定时间到现在注册并且没下过单的用户
                list = ygUserService.findOpenIdByNotOrderWithRegisterTime(StringUtils.isNotBlank(param[0]) ? DateConvertUtils.parse(param[0], "yyyy-MM-dd") : null);
                break;
            case "Vip": // 所有老女王
                list = ygUserService.findWithField("`id` , `open_id` , `is_subscribe`", 10, false,
                        true, true,
                        StringUtils.isNotBlank(param[0]) ? DateConvertUtils.parse(param[0], "yyyy-MM-dd") : null);
                break;
            case "UserAgent": // 所有新女王
                list = ygUserService.findWithField("`id` , `open_id` , `is_subscribe`", null, false,
                        true, true,
                        StringUtils.isNotBlank(param[0]) ? DateConvertUtils.parse(param[0], "yyyy-MM-dd") : null, UserType.UserAgent.name());
                break;
            case "UnUsedCouponAfterRegisterTime": // 指定优惠券（未使用未过期）的用户（指定时间注册）
                List<Long> couponIdList = Arrays.stream(param[1].split(",")).map(Long::valueOf).collect(Collectors.toList());
                list = ygUserService.findOpenIdsByUnUsedCouponId(couponIdList, DateConvertUtils.parse(param[0], "yyyy-MM-dd"));
                break;
            case "All": // 所有关注用户可接收
                list = ygUserService.findWithField("`id` , `open_id` , `is_subscribe`", null, false,
                        true, true,
                        StringUtils.isNotBlank(param[0]) ? DateConvertUtils.parse(param[0], "yyyy-MM-dd") : null);
                break;
            case "NewCustomer": // 所有新用户
                list = ygUserService.findWithField("`id` , `open_id` , `is_subscribe`", null, true,
                        true, true,
                        StringUtils.isNotBlank(param[0]) ? DateConvertUtils.parse(param[0], "yyyy-MM-dd") : null);
                break;
            default:
                list = new ArrayList<>();
                break;
        }
        return list;
    }

    /**
     * 发送到账提醒通知
     *
     * @param userName
     * @return
     */
    @RequestMapping("sendGrowthFundMsg")
    @ResponseBody
    public Message sendGrowthFundMsg(String userName) {
        List<YgUser> userList = getSendUserListWithTest(userName, "UserAgent", null);
        ExecutorService fixedThreadPool = Executors.newFixedThreadPool(10);
        for (YgUser user : userList) {
            fixedThreadPool.execute(() -> wxMpMessageService.sendCouponMsg("妈妈票选夏日好物热销榜新鲜出炉，营养美食、益智玩具、生活必备，45元起买遍全球婴童爆品", "/mall/index.html?sourceCode=293_quan_20180713", user,
                    "100元", DateConvertUtils.formatDateTime(new Date()), "活动最后5天，不要错过哦"));
        }
        fixedThreadPool.shutdown();
        return Message.success(userList.size());
    }

    /**
     * 获取所有微信模板消息
     *
     * @return
     */
    @RequestMapping("findWeixinMessageList")
    @ResponseBody
    public Message findWeixinMessageList() {
        return Message.success(ygWeixinMessageService.findWeixinMessageList());
    }

    /**
     * 刷新模板消息id
     *
     * @param wxMessageType
     * @return
     */
    @RequestMapping("refreshTempleId")
    @ResponseBody
    public Message refreshTempleId(@RequestParam WxMessageType wxMessageType) {
        String key = String.format("wx_tempid_%s", appId + "_" + wxMessageType.name());
        redisDao.del(key.getBytes());
        return Message.success(wxMpMessageService.getWxMsgTempId(wxMessageType));
    }

    /**
     * 模板推送微信消息
     *
     * @param weixinMessage
     * @return
     */
    @RequestMapping("sendWeixinMessageFromTempalte")
    @ResponseBody
    public Message sendWeixinMessageFromTempalte(@RequestParam String weixinMessage) {
        YgWeixinMessage message = JsonUtils.toObject(weixinMessage, YgWeixinMessage.class);
        String[] arr = message.getCreateBy().split(",");
        if (arr == null || arr.length == 0) {
            return Message.success(0);
        }
        List<String> openIdList = getOpenIdList(message.getUserName(), arr[0].trim(), message.getCreateTime(), arr.length > 1 ? arr[1].trim() : null);
        ExecutorService fixedThreadPool = Executors.newFixedThreadPool(10);
        for (String string : openIdList) {
            String openId = string.trim();
            if (StringUtils.isBlank(openId)) {
                continue;
            }
            fixedThreadPool.execute(() -> {
                TemplateMessage tplMessage = new TemplateMessage(openId, message.getTemplateId(), message.getFirstData(), message.getLinkUrl());
                tplMessage.pushHead("#323232", message.getFirstData());
                if (StringUtils.isNotBlank(message.getKeyword1Data())) {
                    tplMessage.pushItem("keyword1", "#323232", message.getKeyword1Data());
                }
                if (StringUtils.isNotBlank(message.getKeyword2Data())) {
                    tplMessage.pushItem("keyword2", "#323232", message.getKeyword2Data());
                }
                if (StringUtils.isNotBlank(message.getKeyword3Data())) {
                    tplMessage.pushItem("keyword3", "#323232", message.getKeyword3Data());
                }
                if (StringUtils.isNotBlank(message.getKeyword4Data())) {
                    tplMessage.pushItem("keyword4", "#323232", message.getKeyword4Data());
                }
                if (StringUtils.isNotBlank(message.getKeyword5Data())) {
                    tplMessage.pushItem("keyword5", "#323232", message.getKeyword5Data());
                }
                tplMessage.pushItem("remark", "#323232", message.getRemarkData());
                wxMpMessageService.sendTemplateMessage(tplMessage);
            });
        }
        fixedThreadPool.shutdown();
        return Message.success(openIdList.size());
    }

    private List<YgUser> getUserList(String testUserName, String userId) {
        if (StringUtils.isNotBlank(testUserName)) {
            return Collections.singletonList(ygUserService.findByUserName(testUserName));
        }
        if (StringUtils.isBlank(userId)) {
            return new ArrayList<>();
        }
        String[] arr = userId.split(",");
        List<YgUser> userList = new ArrayList<>();
        List<Long> idList = new ArrayList<>();
        for (int i = 0; i < arr.length; i++) {
            Long id = Long.valueOf(arr[i]);
            if (idList.contains(id)) {
                continue;
            }
            idList.add(id);
            if (idList.size() == 1000 || i == arr.length - 1) {
                List<YgUser> list = ygUserService.findOpenIds(idList);
                if (CollectionUtils.isNotEmpty(list)) {
                    userList.addAll(list);
                }
                idList.clear();
            }
        }
        return userList;
    }

    @RequestMapping(value = "getUserCount", method = RequestMethod.GET)
    @ResponseBody
    public Message getUserCount(@RequestParam String userType, Date startDate, String couponId) {
        List<String> openIdList = getOpenIdList(null, userType, startDate, couponId);
        return Message.success(CollectionUtils.isEmpty(openIdList) ? 0 : openIdList.size());
    }

    private List<String> getOpenIdList(String testUserName, String userType, Date startDate, String couponId) {
        List<String> openIdList = null;
        if (StringUtils.isNotBlank(testUserName)) {
            openIdList = Collections.singletonList(ygUserService.findByUserName(testUserName).getOpenId());
        } else if ("SubscribeAndNotRegister".equals(userType)) {
            openIdList = ygUserService.findOpenIdByNotRegister();
        } else {
            List<YgUser> sendUserList = getSendUserList(userType, DateConvertUtils.format(startDate), couponId);
            if (!CollectionUtils.isEmpty(sendUserList)) {
                openIdList = sendUserList.stream().map(o -> o.getOpenId()).collect(Collectors.toList());
            }
        }
        return openIdList;
    }

    @RequestMapping(value = "getUserFromFile")
    @ResponseBody
    public Message getUserFromFile(@RequestParam("uploadFile") MultipartFile uploadFile) throws IOException {
        InputStream is = uploadFile.getInputStream();
        byte[] bytes = new byte[1024];
        int length;
        StringBuilder sb = new StringBuilder();
        while ((length = is.read(bytes)) != -1) {
            String text = new String(bytes, 0, length);
            if (StringUtils.isNotBlank(text)) {
                sb.append(text);
            }
        }
        if (sb.length() == 0) {
            return Message.success(null);
        }
        return Message.success(sb.toString().split(",").length);
    }

}
